package com.ss.web.tagmark.dao;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;

@NoRepositoryBean // 指明不需要实例化
public interface BaseRepository<T, ID> extends JpaRepository<T, ID> {
	/**
	 * 列表数据获取
	 * 
	 * @param t
	 * @param page
	 * @param em
	 * @return
	 */
	Page<T> findByPage(T t, Pageable page, EntityManager em);

	/**
	 * 将指定的sql进行count(*)包裹后查询对应的值
	 *
	 * @param sql
	 * @return
	 */
	default int queryCount(String sql, Map<String, Object> params, EntityManager em) {
		javax.persistence.Query q = em.createNativeQuery("select count(*) from (" + sql + ") t");
		if (params != null && params.size() > 0) {
			for (String key : params.keySet()) {
				q.setParameter(key, params.get(key));
			}
		}
		Number n = (Number) q.getSingleResult();
		return n.intValue();
	}

	/**
	 * 查询指定的SQL，获取分页数据
	 *
	 * @param page
	 * @param sql
	 * @param em
	 * @param params
	 * @return
	 */
	@SuppressWarnings("unchecked")
	default Page<T> doQuery(Pageable page, String sql, Class<T> entityClass, Map<String, Object> params,
			EntityManager em) {
		int total = queryCount(sql, params, em);
		// 处理翻页越界问题
		int totalPages = total / page.getPageSize() + (total % page.getPageSize() > 0 ? 1 : 0);
		if (totalPages < page.getPageNumber() + 1) {
			page = PageRequest.of(totalPages > 0 ? totalPages - 1 : 0, page.getPageSize());
		}
		// 排序
		if (page.getSort() != null) {// 添加order
			Iterator<Sort.Order> os = page.getSort().iterator();
			while (os.hasNext()) {
				Sort.Order o = os.next();
				String orderBy = o.getProperty() + " " + o.getDirection().name();
				sql += " " + orderBy;
				break;
			}
		}
		javax.persistence.Query q = em.createNativeQuery(sql, entityClass);
		if (params != null && params.size() > 0) {
			for (String key : params.keySet()) {
				q.setParameter(key, params.get(key));
			}
		}
		List<T> users = q.getResultList();
		return new PageImpl<T>(users, page, total);
	}

}
